<?php
/**
 * This class includes static methods for manipulating a database.<br/>
 * The class is usually used by ORMapper class, 
 * and we usually do not invoke its method directly.<br/>
 * This class do not perform connection pooling.<br/>
 * If you want to manage the connection,
 * you can manually manage the connection in PHP programs with methods whose name ends with WithConnection, 
 * or you can modify this class.<br/>
 * Additionally, you can modify this class for using other databases
 * (originally, phporm supports only MySQL).<br/>
 * 
 * @package lib.famteam.phporm
 * @author polikeiji
 * @static 
 *
 */
class DatabaseManager {

	/**
	 * Get the connection.
	 * 
	 * @return connection database connection
	 */
	public static function getDatabaseConnection() {
		$connection = mysql_connect(DatabaseConfiguration::DATABASE_HOST, DatabaseConfiguration::DATABASE_USER, DatabaseConfiguration::DATABASE_PASSWORD);
		if ($connection) {
			//mysql_query("set names " . DatabaseConfiguration::DATABASE_ENCODING);
			mysql_set_charset(DatabaseConfiguration::DATABASE_ENCODING, $connection);
			if (mysql_select_db(DatabaseConfiguration::DATABASE_NAME, $connection)) {
				return $connection;
			}
			else {
				mysql_close($connection);
				return null;
			}
		}
	}

	/**
	 * Close the connection
	 * 
	 * @param connection $connection Closed connection
	 */
	public static function closeDatabaseConnection($connection) {
		return mysql_close($connection);
	}
	
	/**
	 * Send passed query string which is for updating the database to the database.
	 * 
	 * @param str $queryString
	 * @return bool Success or failed of sending the query
	 */
	public static function doUpdateQuery($queryString) {
		Logger::sqlLog($queryString);
		$connection = DatabaseManager :: getDatabaseConnection();
		if ($connection != null) {
			if (mysql_query($queryString, $connection)) {
				DatabaseManager :: closeDatabaseConnection($connection);
				return true;
			} else {
				Logger::sqlLog(mysql_error($connection));
				DatabaseManager :: closeDatabaseConnection($connection);
				return false;
			}
		} else {
			return false;
		}
	}
	
	/**
	 * Send passed query string which is for updating the database to the database.
	 * You can use this method when you manually manage database connection.
	 * 
	 * @param str $queryString
	 * @param connection $connection
	 * @return bool Success or failed of sending the query
	 */
	public static function doUpdateQueryWithConnection($queryString, $connection) {
		Logger::sqlLog($queryString);
		if ($connection != null) {
			if (mysql_query($queryString, $connection)) {
				return true;
			} else {
				Logger::sqlLog(mysql_error($connection));
				DatabaseManager :: closeDatabaseConnection($connection);
				return false;
			}
		} else {
			return false;
		}
	}
	
	/**
	 * Send passed query string which is for gathering data from the database to the database.
	 * 
	 * @param str $queryString
	 * @return mixed Array which includes each row data of the database. When performing the query is failed, false is returned.
	 */
	public static function doSelectQuery($queryString) {
		Logger::sqlLog($queryString);
		$connection = DatabaseManager :: getDatabaseConnection();
		if ($connection != null) {
			if ($result = mysql_query($queryString, $connection)) {
				$returnArray = array ();
				while ($rowObject = mysql_fetch_object($result)) {
					$returnArray[] = DatabaseLibrary :: convertField($rowObject);
				}
				DatabaseManager :: closeDatabaseConnection($connection);
				return $returnArray;
			}
			else {
				DatabaseManager :: closeDatabaseConnection($connection);
				return false;
			}
		}
		else {
			return false;
		}
	}
	
	/**
	 * Send passed query string which is for gathering data from the database to the database.
	 * You can use this method when you manually manage database connection.
	 * 
	 * @param str $queryString
	 * @return mixed Array which includes each row data of the database. When performing the query is failed, false is returned.
	 */
	public static function doSelectQueryWithConnection($queryString, $connection) {
		Logger::sqlLog($queryString);
		if ($connection != null) {
			if ($result = mysql_query($queryString, $connection)) {
				$returnArray = array ();
				while ($rowObject = mysql_fetch_object($result)) {
					array_push($returnArray, DatabaseLibrary :: convertField($rowObject));
				}
				return $returnArray;
			} else {
				DatabaseManager :: closeDatabaseConnection($connection);
				return null;
			}
		} else {
			return null;
		}
	}

	/**
	 * 
	 * @param connection $connection
	 * @return number Null is returned when querying is failed.
	 */
	public static function getLastInsertID($connection) {
		$query = 'select last_insert_id()';
		Logger::sqlLog($query);
		$result = DatabaseManager::doSelectQueryWithConnection($query, $connection);
		if ($result != null) {
			if (count($result) == 1) {
				$lastInsertID = $result[0];
				$lastInsertIDKey = "last_insert_id()";
				return $lastInsertID->$lastInsertIDKey;
			}
			else {
				return null;
			}
		} else {
			mysql_close($connection);
			return null;
		}
	}
	
	/**
	 * 
	 * @param str $queryString A select query which includes count function
	 * @return number Null is returned when querying is failed.
	 */
	public static function getCount($queryString) {
		Logger::sqlLog($queryString);
		$result = DatabaseManager::doSelectQuery($queryString);
		return DatabaseManager::_getOneResult($result, "count(*)");
	}
	
	/**
	 * 
	 * @param str $queryString A select query which includes count function
	 * @return number Null is returned when querying is failed.
	 */
	public static function getCountWithConnection($queryString, $connection) {
		Logger::sqlLog($queryString);
		$result = DatabaseManager::doSelectQueryWithConnection($queryString, $connection);
		return DatabaseManager::_getOneResult($result, "count(*)");
	}
	
	/**
	 * 
	 * @param object $result
	 * @param str $selectExpression
	 * @return mixed 
	 */
	private static function _getOneResult($result, $selectExpression) {
		if ($result != null) {
			if (count(($result)) == 1) {
				$countRow = $result[0];
				return $countRow->$selectExpression;
			}
			else {
				return null;
			}
		}
		else {
			return null;
		}
	}
	
	/**
	 * 
	 * @param str $queryString
	 * @param str $columnName
	 * @param connection $connection
	 * @return number
	 */
	public static function getMaxWithConnection($queryString, $columnName, $connection) {
		$result = DatabaseManager::doSelectQueryWithConnection($queryString, $connection);
		return DatabaseManager::_getOneResult($result, 'max(' . $columnName . ')');
	}
	
	/**
	 * 
	 * @param str $queryString
	 * @param str $columnName
	 * @param connection $connection
	 * @return number
	 */
	public static function getMinWithConnection($queryString, $columnName, $connection) {
		$result = DatabaseManager::doSelectQueryWithConnection($queryString, $connection);
		return DatabaseManager::_getOneResult($result, 'min(' . $columnName . ')');
	}
}
?>
